package com.gzhryc.common.event;

import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.atomic.AtomicBoolean;

import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;

/**
 * 定时延迟处理服务
 * @author ty
 * @version 2020-5-12
 */
public class TimerDelayHandleService {
	
	static Logger log = Logger.getLogger(TimerDelayHandleService.class);
	
	static TimerDelayHandleService self;
	
	public static TimerDelayHandleService get() {
		if(self == null) {
			self = new TimerDelayHandleService();
		}
		return self;
	}

	DelayQueue<TimerDelayEvent> Queue = new DelayQueue<TimerDelayEvent>();  //使用待延迟的队列
	AtomicBoolean isRun = new AtomicBoolean(false);
	ConcurrentHashMap<Integer,Task> Tasks = new ConcurrentHashMap<Integer,Task>();
	AbsTimerDelayHandler<?> Handler = new DefaultDelayHandler();
	
	public TimerDelayHandleService() {
		this.Queue = new DelayQueue<TimerDelayEvent>();
		this.Tasks = new ConcurrentHashMap<Integer,Task>();
		this.Handler = new DefaultDelayHandler();
		this.isRun = new AtomicBoolean(false);
	}
	
	/**
	 * 添加延迟处理程序
	 * @param handler
	 */
	public <T extends AbsTimerDelayHandler<?>> void addHandler(T handler){
		Handler.setNextHandler(handler);
	}
	
	/**
	 * 添加延迟事件
	 * @param event
	 * @return
	 */
	public <T extends TimerDelayEvent> boolean addEvent(TimerDelayEvent event){
		if(isRun.get()){
			Queue.put(event);
			return true;
		}
		return false;
	}
	
	/**
	 * 启动服务
	 * @param threadNum	线程数
	 */
	public void run(int threadNum){
		if(isRun.compareAndSet(false, true)) {
			for(int i=0;i<threadNum;i++){
				Task task = new Task(i);
				Tasks.put(task.getIndex(), task);
				task.start();
			}
			log.debug("启动延迟执行服务");
		}
	}
	
	/**
	 * 关闭服务
	 */
	public void close(){
		if(isRun.compareAndSet(true, false)) {
			int total = Tasks.size();
			for(int i=0;i<total;i++){
				Queue.add(new EmptyDelayEvent());
			}
		}
	}
	
	public boolean isRun() {
		return this.isRun.get();
	}
	
	public boolean contains(Class<?> clazz) {
		return contains(Handler,clazz);
	}
	
	private boolean contains(AbsTimerDelayHandler<?> handler,Class<?> clazz) {
		if(handler.getClass().equals(clazz)) {
			return true;
		}else if(handler.getNextHandler() != null) {
			return contains(handler.getNextHandler(),clazz);
		}
		return false;
	}
	
	private class Task extends Thread {
		
		final Integer index;
		
		public Task(Integer index){
			this.index = index;
		}

		public void run(){
			while(isRun.get()){
				try{
					TimerDelayEvent event = Queue.take();
					Handler.intercept(event);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			//移除自己
			Tasks.remove(index);
			System.out.println("～～延迟执行线程结束生命～～");
		}
		
		public Integer getIndex(){
			return this.index;
		}
	}
	
	public class EmptyDelayEvent extends TimerDelayEvent implements Serializable {

		private static final long serialVersionUID = 1L;

		@Override
		public Long getExecuteTimes() {
			return 0L;
		}
	}

	public class DefaultDelayHandler extends AbsTimerDelayHandler<EmptyDelayEvent> {
		@Override
		public boolean execute(EmptyDelayEvent event) {
			log.debug("未处理事件："+JsonTools.toJson(event));
			return true;
		}
	}
}
